#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

struct Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	~Date()
	{
		cout << "~Date()" << endl;
	}
};
namespace sty
{
	template<class T>
	class shared_ptr
	{
	public:
		shared_ptr(T* ptr = nullptr)
			:_ptr(ptr)
			,_pcount(new int(1))
		{}

		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			,_pcount(sp._pcount)
		{
			(*_pcount)++;
		}
		
		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr != sp._ptr)
			{
				if (--(*_pcount) == 0)
				{
					delete _ptr;
					delete _pcount;
				}
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				(*_pcount)++;
				
			}

			return *this;

		}


		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}



		~shared_ptr()
		{
			if (--(*_pcount) == 0)
			{
				delete _ptr;
				delete _pcount;
			}
		}
	private:
		T* _ptr;
		int* _pcount;
	};
}
int main()
{
	sty::shared_ptr<Date> sp1(new Date);
	// ⽀持拷⻉ 
	sty::shared_ptr<Date> sp2(sp1);
	sty::shared_ptr<Date> sp3(sp2);

	sty::shared_ptr<Date> sp4(new Date);

	sp1 = sp4;
}



//template<class T>
//class unique_ptr
//{
//public:
//	explicit unique_ptr(T* ptr)
//		:_ptr(ptr)
//	{}
//	~unique_ptr()
//	 {
//		if (_ptr)
//		{
//			cout << "delete:" << _ptr << endl;
//			delete _ptr;
//		}
//	}
//	// 像指针⼀样使⽤ 
//	T& operator*()
//	{
//		return *_ptr;
//	}
//	T* operator->()
//	{
//		return _ptr;
//	}
//	unique_ptr(const unique_ptr<T>& sp) = delete;
//	unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;
//	unique_ptr(unique_ptr<T>&& sp)
//		:_ptr(sp._ptr)
//	{
//		sp._ptr = nullptr;
//	}
//	unique_ptr<T>& operator=(unique_ptr<T>&& sp)
//	{
//		delete _ptr;
//		_ptr = sp._ptr;
//		sp._ptr = nullptr;
//	}
//private:
//	T* _ptr;
//};




template<class T>
class shared_ptr
{
public:
	explicit shared_ptr(T* ptr = nullptr)
		: _ptr(ptr)
		, _pcount(new int(1))
	{}

	//template <class D>
	//shared_ptr(T * ptr, D del)
	//	: _ptr(ptr)
	//	, _pcount(new int(1))
	//	, _del(del)
	//{}

	shared_ptr(const shared_ptr<T>& sp)
		:_ptr(sp._ptr)
		, _pcount(sp._pcount)
		, _del(sp._del)
	{
		++(*_pcount);
	}

	void release()
	{
		if (--(*_pcount) == 0)
		{
			// 最后⼀个管理的对象，释放资源 
			_del(_ptr);
			delete _pcount;
			_ptr = nullptr;
			_pcount = nullptr;
		}
	}
	shared_ptr<T>& operator=(const shared_ptr<T>& sp)
	{
		if (_ptr != sp._ptr)
		{
			release();
			_ptr = sp._ptr;
			_pcount = sp._pcount;
			++(*_pcount);
			_del = sp._del;
		}
		return *this;
	}
	~shared_ptr()
	{
		release();
	}
	T* get() const
	{
		return _ptr;
	}
	int use_count() const
	{
		return *_pcount;
	}
	T& operator*()
	{
		return *_ptr;
	}
	T* operator->()
	{
		return _ptr;
	}
private:
	T* _ptr;
	int* _pcount;
	//function<void(T*)> _del = [](T* ptr) {delete ptr; };
};






struct ListNode
{
	int _data;
	std::shared_ptr<ListNode> _next;
	std::shared_ptr<ListNode> _prev;

	// 这⾥改成weak_ptr，当n1->_next = n2;绑定shared_ptr时 
	// 不增加n2的引⽤计数，不参与资源释放的管理，就不会形成循环引⽤了 
	/*std::weak_ptr<ListNode> _next;
	std::weak_ptr<ListNode> _prev;*/
	~ListNode()
	{
		cout << "~ListNode()" << endl;
	}
};
int main()
{
	// 循环引⽤ -- 内存泄露 
	std::shared_ptr<ListNode> n1(new ListNode);
	std::shared_ptr<ListNode> n2(new ListNode);
	cout << n1.use_count() << endl;
	cout << n2.use_count() << endl;
	n1->_next = n2;
	n2->_prev = n1;
	cout << n1.use_count() << endl;
	cout << n2.use_count() << endl;
	// weak_ptr不⽀持管理资源，不⽀持RAII 
	// weak_ptr是专⻔绑定shared_ptr，不增加他的引⽤计数，作为⼀些场景的辅助管理 
	//std::weak_ptr<ListNode> wp(new ListNode);
	return 0;
}
template<class T>
class weak_ptr
{
public:
	weak_ptr()
	{}
	weak_ptr(const shared_ptr<T>& sp)
		:_ptr(sp.get())
	{}
	weak_ptr<T>& operator=(const shared_ptr<T>& sp)
	{
		_ptr = sp.get();
		return *this;
	}
private:
	T * _ptr = nullptr;
};

